// StreamArchive.h: interface for the CStreamArchive class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_STREAMARCHIVE_H__78E1A175_7AE5_4F89_94DB_D778005EC2DC__INCLUDED_)
#define AFX_STREAMARCHIVE_H__78E1A175_7AE5_4F89_94DB_D778005EC2DC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "stdafx.h"

class CStreamArchive
{
public:
	CStreamArchive(IStreamPtr& streamref, UINT nMode)
	{
		stream = streamref;
		m_nMode = nMode;
		if(nMode == CArchive::store)
		{
			try
			{
				pMemFile = new CMemFile();
				pAr = new CArchive(pMemFile, CArchive::store);
			}
			catch (CMemoryException* pEx)
			{
				pEx->ReportError();
				pEx->Delete ();
				TRACE(_T("Memory exception in construct stream archive to store!\n"));
			}
		}
		else if(nMode == CArchive::load)
		{
			try
			{
				DWORD dwDataSize;
				ULONG cb;
				stream->Read(&dwDataSize, sizeof(DWORD), &cb);
				BYTE* lpbData = new BYTE[dwDataSize];
				stream->Read(lpbData, dwDataSize, &cb);
				pMemFile = new CMemFile();
				pMemFile->Attach(lpbData, cb);
				pAr = new CArchive(pMemFile, CArchive::load);
			}
			catch (CMemoryException* pEx)
			{
				pEx->ReportError();
				pEx->Delete ();
				TRACE(_T("Memory exception in construct stream archive to load!\n"));
			}
		} else 
		{
			pMemFile = NULL;
			pAr = NULL;
		}
	}
	
	virtual ~CStreamArchive()
	{
		if(m_nMode == CArchive::store)
		{
			if(pAr)
			{
				pAr->Flush();
				delete pAr;
			}
			
			if(stream)
			{
				if(pMemFile)
				{
					DWORD dwDataSize = pMemFile->GetLength();
					LPBYTE lpbData = pMemFile->Detach();
					if (lpbData != NULL)
					{
						ULONG cb;
						stream->Write(&dwDataSize, sizeof(DWORD), &cb);
						stream->Write(lpbData, (UINT)dwDataSize, &cb);
						delete[] lpbData;
					}
				}
				stream.Release();
			}
		} 
		else if (m_nMode == CArchive::load)
		{
			if(pAr)
			{
				pAr->Close();
				delete pAr;
			}
			
			if(stream)
			{
				if(pMemFile)
				{
					LPBYTE lpbData = pMemFile->Detach();
					delete[] lpbData;
				}
				stream.Release();
			}
		}
		
		if(pMemFile)
		delete pMemFile;
	}

public:
	CArchive&	GetArchive() { return *pAr; }

protected:
	UINT		m_nMode;
	IStreamPtr	stream;
	CMemFile*	pMemFile;
	CArchive*	pAr;
};

#endif // !defined(AFX_STREAMARCHIVE_H__78E1A175_7AE5_4F89_94DB_D778005EC2DC__INCLUDED_)
